<?php
/**
 * CreateTime: 2023/11/16 18:59
 * User:LinQ
 */

namespace App\Models;

use App\Facade\UserFuncFacade;
use App\Models\CompanyDepartment\CompanyModel;
use App\Models\Users\UsersModel;
use Illuminate\Database\Eloquent\Model;
use JetBrains\PhpStorm\ArrayShape;

class BasicModel extends Model
{
    public $timestamps = true;

    // 用于保存 filters
    protected array $cFilters = [];

    /**
     * push 进 $cFilters 自动进行过滤 如果当前key 未在 fillable 中配置则无效
     * @param $key
     * @param $value
     * @param string $op
     */
    public function pushFilter($key, $value, string $op = "="){
        if(in_array($key,$this->fillable)){
            $this->cFilters[] = [
                'key' => $key,
                'value' => $value,
                'op' => $op
            ];
        }
    }

    /**
     * 自动筛选器
     * @param $query
     * @return mixed
     */
    protected function setFilters($query){
        if($this->cFilters){
            foreach($this->cFilters as $filter){
                switch ($filter['op']){
                    case "in":
                        $query = $query->whereIn($filter['key'],$filter['value']);
                        break;
                    case "notNull":
                        $query = $query->whereNotNull($filter['key']);
                        break;
                    case "null":
                        $query = $query->whereNull($filter['key']);
                        break;
                    case "like":
                        $query = $query->where($filter['key'],$filter['op'],"%".$filter['value']."%");
                        break;
                    case "%like":
                        $query = $query->where($filter['key'],$filter['op'],"%".$filter['value']);
                        break;
                    case "like%":
                        $query = $query->where($filter['key'],$filter['op'],$query = $filter['value']."%");
                        break;
                    default:
                        $query = $query->where($filter['key'],$filter['value']);
                }

            }
        }
        return $query;
    }

    /**
     * 封装的list方法
     * @param mixed $query  模型
     * @param int $page_size  分页大小
     * @param array $select  查询条件
     * @param array $desc 排序条件 默认用创建时间
     * @return array
     */
    #[ArrayShape([
        'data' => "mixed",
        'current_page' => "mixed",
        'last_page' => "mixed",
        'total' => "mixed",
        'per_page' => "mixed"])
    ]
    public function cList($query, $page_size,$desc = [],$select = ['*']): array
    {
        $query = $this->setFilters($query);
        // 给列表自动添加key
        if($this->primaryKey != 'id'){
            $select = array_merge($select,[$this->primaryKey." as key "]);
        }
        $query = $query->select($select);
        if ($desc && map_has_value($desc, 'key') &&
            in_array($desc['key'], $this->getFillable()) &&
            map_has_value($desc, 'order') &&
            ($desc['order'] == "desc" || $desc['order'] == "asc"))
        {
            $query = $query->orderBy($desc['key'], $desc['order']);
        }else{
            $query = $query->latest();
        }
        $data = $query->Paginate($page_size);
        return [
            'data' => $data->items(),
            'current_page'=> $data->currentPage(),
            'last_page' => $data->lastPage(),
            'total' => $data->total(),
            'per_page' => $data->perPage(),
        ];
    }

    /**
     * 封装的list方法
     * @param mixed $query  模型
     * @param int $page_size  分页大小
     * @param array $select  查询条件
     * @param array $desc 排序条件 默认用创建时间
     * @return array
     */
    #[ArrayShape([
        'data' => "mixed",
        'current_page' => "mixed",
        'last_page' => "mixed",
        'total' => "mixed",
        'per_page' => "mixed"])
    ]
    public function cListHasCom($query, $page_size,$desc = [],$select = ['*']): array
    {
        $query = $this->setFilters($query);
        // 给列表自动添加key
        if($this->primaryKey != 'id'){
            $select = array_merge($select,[$this->primaryKey." as key "]);
        }
        $comId = UserFuncFacade::getCurrentComId();
        $query = $query->select($select)->where('com_id',$comId);
        if ($desc && map_has_value($desc, 'key') &&
            in_array($desc['key'], $this->getFillable()) &&
            map_has_value($desc, 'order') &&
            ($desc['order'] == "desc" || $desc['order'] == "asc"))
        {
            $query = $query->orderBy($desc['key'], $desc['order']);
        }else{
            $query = $query->latest();
        }

        $data = $query->Paginate($page_size);
        return [
            'data' => $data->items(),
            'current_page'=> $data->currentPage(),
            'last_page' => $data->lastPage(),
            'total' => $data->total(),
            'per_page' => $data->perPage(),
        ];
    }

    /**
     * 默认新增公司id scope 这个方法一定要放在查询的第一位
     * @return mixed
     */
    public function scopeAddComIdWhere(): mixed
    {
        return $this->where('com_id',UserFuncFacade::getCurrentComId());
    }

    /**
     * 内置创建人枚举，若筛选查询 owner_str 则可以通过 owner_id as owner_str自动转换枚举
     * @param $value
     * @return string
     */
    public function getOwnerStrAttribute($value): string
    {
        $value = (int)$value;
        if($value=== -1){
            return "系统管理员";
        }
        return UsersModel::select(['user_id','name'])->find($value)->name ?? "-";
    }


    /**
     * 内置创建人枚举，若筛选查询 owner_str 则可以通过 owner_id as owner_str自动转换枚举
     * @param $value
     * @return string
     */
    public function getComStrAttribute($value): string
    {
        $value = (int)$value;
        return CompanyModel::select(['company_name'])->find($value)->company_name ?? "-";
    }
}
